# coding=utf-8
# -*- coding: UTF-8 -*-
#
# This file is part of the kernelstudio package.
#
# (c) 2014-2025 zlin <admin@kernelstudio.com>
#
# For the full copyright and license information, please view the LICENSE file
# that was distributed with this source code.
import io
import logging
import typing as t

import yaml
from pptx import Presentation

from ksai.document.context import DocumentSection
from ksai.document.converter.attachment import convert_attachment
from ksai.document.extractor.extractor import AbstractDocumentExtractor, DocumentExtractorException
from ksai.document.utils.word import table_to_markdown
from ksai.persistence.storage.attachment import Attachment

logger = logging.getLogger(__name__)


class PptxDocumentExtractor(AbstractDocumentExtractor):

    def __init__(self):
        super().__init__()

    def do_extract(self, attachment: Attachment) -> t.List[DocumentSection]:
        try:
            prs = Presentation(io.BytesIO(convert_attachment(attachment, 'pptx')))
            documents = []
            for slide_number, slide in enumerate(prs.slides, 1):
                slide_text = []
                for shape in slide.shapes:
                    if shape.has_text_frame:
                        # 提取普通文本
                        for paragraph in shape.text_frame.paragraphs:
                            for run in paragraph.runs:
                                slide_text.append(run.text)
                    try:
                        if shape.has_table:
                            # 提取表格中的文本
                            table = shape.table
                            slide_text.append("\n".join(table_to_markdown(table)))
                    except Exception as e:
                        logger.warning(f"Failed extract pptx table: {e}")
                        continue

                documents.append(DocumentSection(
                    text="\n".join(slide_text),
                    page=slide_number,
                ))

            return documents
        except (UnicodeDecodeError, yaml.YAMLError) as e:
            raise DocumentExtractorException(f"Extract pptx file error: {e}") from e

    def extensions(self) -> t.List[str]:
        return ["ppt", "pptx"]

    def mimes(self) -> t.List[str]:
        return ["application/vnd.ms-powerpoint",
                "application/vnd.openxmlformats-officedocument.presentationml.presentation"]
